package pers.cj.pdos.controller;


import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ResponseBody;
import pers.cj.pdos.controller.base.BaseController;
import pers.cj.pdos.controller.entity.ResponseData;
import pers.cj.pdos.controller.entity.ResponseEntity;
import pers.cj.pdos.controller.entity.ResponseList;
import pers.cj.pdos.entity.*;
import pers.cj.pdos.excel.ExcelJoinSplit;
import pers.cj.pdos.service.IJoinSplitService;
import pers.cj.pdos.task.CleanTempExcelTask;
import pers.cj.pdos.utils.*;
import pers.cj.pdos.vo.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * <p>
 * 拆卸后的价格要高于原价格
 前端控制器
 * </p>
 *
 * @author chenj
 * @since 2019-11-04
 */
@Controller
@RequestMapping("/house")
public class JoinSplitController extends BaseController {
    @Autowired
    IJoinSplitService joinSplitService;

    @RequiresPermissions("joinSplit:query")
    @RequestMapping("/joinSplit")
    public String joinSplit(){
        return "joinSplit/joinSplit";
    }

    @RequiresPermissions("joinSplit:insert")
    @RequestMapping("/joinSplitNew")
    public String joinSplitNew(){
        return "joinSplit/joinSplitNew";
    }

    @RequiresPermissions("joinSplit:query")
    @RequestMapping("/joinSplitDetail")
    public String joinSplitDetail(Model model, String id){
        model.addAttribute("id",id);
        return "joinSplit/joinSplitDetail";
    }

    @ResponseBody
    @RequiresPermissions("joinSplit:query")
    @RequestMapping("/joinSplit/getList")
    public ResponseList getList(int page,
                                int limit,
                                String close,
                                String search,
                                String no,
                                String goodsName,
                                String remark,
                                String date1,
                                String date2,
                                String oldStoreId,
                                String newStoreId,
                                String userId,
                                String makeTime1,
                                String makeTime2,
                                String oldHouseId,
                                String newHouseId,
                                String makeUserId){
        Company company = getCompany();
        UserVo userVo = getLoginUserVo();

        List<JoinSplitVo> list = joinSplitService.listVo(company.getId(),
                page,
                limit,
                Utils.genBoolean(close),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genDate(date1),
                Utils.genDate(date2),
                oldStoreId,
                newStoreId,
                PdosUtils.getViewOrderStoreId(userVo,null),
                PdosUtils.getViewOrderUserId(userVo,userId),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                oldHouseId,
                newHouseId,
                makeUserId);
        long count = joinSplitService.count(company.getId(),
                Utils.genBoolean(close),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genDate(date1),
                Utils.genDate(date2),
                oldStoreId,
                newStoreId,
                PdosUtils.getViewOrderStoreId(userVo,null),
                PdosUtils.getViewOrderUserId(userVo,userId),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                oldHouseId,
                newHouseId,
                makeUserId);
        return ResponseList.success(count,list);
    }

    @ResponseBody
    @RequiresPermissions("joinSplit:insert")
    @RequestMapping("/joinSplit/add")
    public ResponseEntity add(@RequestBody JoinSplitVo joinSplitVo) {
        Company company = getCompany();

        if (Utils.isEmpty(joinSplitVo.getNo())){
            return ResponseEntity.fail("编号不能为空");
        }

        if (Utils.isEmpty(joinSplitVo.getJoinSplitOldGoodsVoList())){
            return ResponseEntity.fail("请选择原商品清单");
        }

        if (Utils.isEmpty(joinSplitVo.getJoinSplitNewGoodsVoList())){
            return ResponseEntity.fail("请选择新商品清单");
        }

        if (joinSplitVo.getDate() == null){
            return ResponseEntity.fail("业务日期不能为空");
        }

        if (Utils.isEmpty(joinSplitVo.getOldHouseId())){
            return ResponseEntity.fail("请选择出库仓库");
        }

        if (Utils.isEmpty(joinSplitVo.getNewHouseId())){
            return ResponseEntity.fail("请选择入库仓库");
        }

        if (joinSplitVo.getOldTotalAmt().compareTo(joinSplitVo.getNewTotalAmt()) == 1) {
            return ResponseEntity.fail("新商品总金额不能小于原商品总金额，请重新修改");
        }

        if (joinSplitService.checkNo(joinSplitVo.getNo(),company.getId())){
            return ResponseEntity.fail("编号已被使用");
        }


        if (getHouseLocking(joinSplitVo.getOldHouseId())) {
            return ResponseEntity.fail("出库仓库被锁定，请更换仓库");
        }

        if (getHouseLocking(joinSplitVo.getNewHouseId())) {
            return ResponseEntity.fail("入库仓库被锁定，请更换仓库");
        }

        //原商品清单是出库的，所以需要检查其库存
        GoodsUtil goodsUtil = new GoodsUtil(joinSplitVo.getOldHouseId(), joinSplitVo.getJoinSplitOldGoodsVoList());
        String msg = goodsUtil.checkStock();
        if (!Utils.isEmpty(msg)){
            return ResponseEntity.fail(msg);
        }

        JoinSplit joinSplit = DataUtil.genEntityFromVo(JoinSplit.class, joinSplitVo);
        DataUtil.processEntity(company,joinSplit);
        joinSplit.setClose(false);
        joinSplit.setMakeTime(joinSplit.getTime());
        joinSplit.setMakeUserId(getLoginUserId());

        //原商品清单准备 - 出库
        List<JoinSplitOldGoods> oldGoodsList = new ArrayList<>();
        List<GoodsSn> oldGoodsSnList = new ArrayList<>();
        List<GoodsSnLog> oldGoodsSnLogList = new ArrayList<>();
        for (JoinSplitOldGoodsVo vo:joinSplitVo.getJoinSplitOldGoodsVoList()) {
            JoinSplitOldGoods entity = DataUtil.genEntityFromVo(JoinSplitOldGoods.class, vo);
            DataUtil.processEntity(company,entity);
            entity.setJoinSplitId(joinSplit.getId());
            oldGoodsList.add(entity);

            if (!Utils.isEmpty(vo.getGoodsSnList())){
                for (GoodsSn goodsSn : vo.getGoodsSnList()) {
                    oldGoodsSnList.add(goodsSn);

                    GoodsSnLog log = new GoodsSnLog();
                    DataUtil.processEntity(company,log);
                    log.setGoodsId(goodsSn.getGoodsId());
                    log.setSn(goodsSn.getSn());
                    log.setType(13);
                    log.setJoinSplitOldGoodsId(entity.getId());
                    oldGoodsSnLogList.add(log);
                }
            }
        }

        //新商品清单准备-入库
        List<JoinSplitNewGoods> newGoodsList = new ArrayList<>();
        List<GoodsSn> newGoodsSnList = new ArrayList<>();
        List<GoodsSnLog> newGoodsSnLogList = new ArrayList<>();
        Map<String,Object> snInitMap = new HashMap<>();
        snInitMap.put("inDate", new Date());//设置入库日期
        snInitMap.put("status", 1);//设置状态为未出库
        for (JoinSplitNewGoodsVo vo:joinSplitVo.getJoinSplitNewGoodsVoList()) {
            JoinSplitNewGoods entity = DataUtil.genEntityFromVo(JoinSplitNewGoods.class, vo);
            DataUtil.processEntity(company,entity);
            entity.setJoinSplitId(joinSplit.getId());
            newGoodsList.add(entity);

            if (!Utils.isEmpty(vo.getGoodsSnList())){
                for (GoodsSn goodsSn : vo.getGoodsSnList()) {
                    DataUtil.processEntity(company, goodsSn,snInitMap);
                    newGoodsSnList.add(goodsSn);

                    GoodsSnLog log = new GoodsSnLog();
                    DataUtil.processEntity(company,log);
                    log.setGoodsId(goodsSn.getGoodsId());
                    log.setSn(goodsSn.getSn());
                    log.setType(14);
                    log.setJoinSplitNewGoodsId(entity.getId());
                    newGoodsSnLogList.add(log);
                }
            }
        }

        joinSplitService.insert(joinSplit, oldGoodsList, oldGoodsSnList,oldGoodsSnLogList, newGoodsList, newGoodsSnList, newGoodsSnLogList);

        return ResponseEntity.success();
    }

    @ResponseBody
    @RequiresPermissions("joinSplit:close")
    @RequestMapping("/joinSplit/close")
    public ResponseEntity close(@RequestBody JoinSplit joinSplit){
        //检查是否已经关闭
        if (joinSplitService.checkClose(joinSplit)){
            return ResponseEntity.fail("该单据已被关闭，不能重复关闭");
        }

        try {
            joinSplitService.close(joinSplit);
            return ResponseEntity.success();
        }catch (Exception e) {
            return ResponseEntity.fail("关闭订单失败");
        }
    }

    @ResponseBody
    @RequestMapping("/joinSplit/getVoById")
    public ResponseData getVoById(String id) {
        return ResponseData.success(joinSplitService.getVoById(id));
    }

    /**
     * 先更具请求数据
     * @throws IOException
     */
    @ResponseBody
    @RequiresPermissions("joinSplit:export")
    @RequestMapping("/joinSplit/export")
    public ResponseData export(String close,
                               String search,
                               String no,
                               String goodsName,
                               String remark,
                               String date1,
                               String date2,
                               String oldStoreId,
                               String newStoreId,
                               String userId,
                               String makeTime1,
                               String makeTime2,
                               String oldHouseId,
                               String newHouseId,
                               String makeUserId){
        Company company = getCompany();
        UserVo userVo = getLoginUserVo();

        List<JoinSplitVo> list = joinSplitService.listVo(company.getId(),
                null,
                null,
                Utils.genBoolean(close),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genDate(date1),
                Utils.genDate(date2),
                oldStoreId,
                newStoreId,
                PdosUtils.getViewOrderStoreId(userVo,null),
                PdosUtils.getViewOrderUserId(userVo,userId),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                oldHouseId,
                newHouseId,
                makeUserId);

        String fileName = "组装拆卸单列表" + DateUtils.getDate(new Date(), DateUtils.YYYYMMDDHHMMSSSS) + ".xlsx";
        try {
            String path = FileProperUtil.getInstance().getVal("excel.temp");
            OutputStream out = new FileOutputStream(path+fileName);
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX,true);
            Sheet sheet1 = new Sheet(1,0, ExcelJoinSplit.class);
            sheet1.setSheetName("组装拆卸单信息");
            writer.write(genExcelList(list), sheet1);
            writer.finish();
            out.close();
            CleanTempExcelTask.put(fileName,new Date().getTime());
            return ResponseData.success(fileName);
        } catch (IOException e) {
            return ResponseData.fail("订单列表导出失败");
        }
    }

    private List<ExcelJoinSplit> genExcelList(List<JoinSplitVo> joinSplitVoList) {
        BusinessSet businessSet = getBusinessSet();
        List<ExcelJoinSplit> list = new ArrayList<>();
        for (JoinSplitVo vo : joinSplitVoList) {
            ExcelJoinSplit excel = new ExcelJoinSplit();
            excel.setDate(DateUtils.getDate(vo.getDate(), DateUtils.YYYY_MM_DD));
            excel.setNo(vo.getNo());
            String oldGoods = "";
            for (JoinSplitOldGoodsVo goodsVo : vo.getJoinSplitOldGoodsVoList()){
                oldGoods += goodsVo.getGoodsVo().getName() + "、";
            }
            oldGoods = oldGoods.substring(0,oldGoods.length()-1);
            excel.setOldGoods(oldGoods);
            excel.setOldStore(vo.getOldHouseVo().getStore().getName());
            excel.setOldHouse(vo.getOldHouseVo().getName());
            excel.setOldTotalAmt(PdosUtils.getPrice(vo.getOldTotalAmt(),businessSet));

            String newGoods = "";
            for (JoinSplitNewGoodsVo goodsVo : vo.getJoinSplitNewGoodsVoList()){
                newGoods += goodsVo.getGoodsVo().getName() + "、";
            }
            newGoods = newGoods.substring(0,newGoods.length()-1);
            excel.setNewGoods(newGoods);
            excel.setNewStore(vo.getNewHouseVo().getStore().getName());
            excel.setNewHouse(vo.getNewHouseVo().getName());
            excel.setOldTotalAmt(PdosUtils.getPrice(vo.getNewTotalAmt(),businessSet));
            excel.setUser(vo.getUser().getName());
            excel.setMakeUser(vo.getMakeUser().getName());
            excel.setClose(vo.getClose() ? "是":"否");
            list.add(excel);
        }

        return list;
    }
}
